#============================================================
#    Priority Callable Connector
#============================================================
# - datetime: 2022-11-23 12:49:58
#============================================================
##优先级回调连接器
##[br]
##[br]使 callable 带有有优先级，使调用的 [Callable] 拥有先后顺序
class_name PriorityCallableConnector


## 当前对应 id 的优先级队列
const PRIORITY_CALLABLE_QUEUE_DATA = {
	"id": "_PRIORITY_SIGNAL_QUEUE_DATA_id",
	"autoincrement": 0,
}


## 信号对应的 Callable 队列
var _signal_to_queue_map : Dictionary = {}


##  实例化这个对象的连接器
##[br]
##[br][code]id[/code]  这个 ID 的 [PriorityCallableConnector] 对象，防止重复创建。这个
##ID可以是任何类型的值，int、float、String、Object 等等
##[br]
##[br][code]return[/code]  返回这个优先级队列连接器
static func instance(id) -> PriorityCallableConnector:
	if PRIORITY_CALLABLE_QUEUE_DATA.has(id):
		return PRIORITY_CALLABLE_QUEUE_DATA[id] as PriorityCallableConnector
	else:
		PRIORITY_CALLABLE_QUEUE_DATA[id] = PriorityCallableConnector.new()
		return PRIORITY_CALLABLE_QUEUE_DATA[id] as PriorityCallableConnector


##  添加优先级队列 [Callable]
##[br]
##[br][code]id[/code]  添加到的队列ID
##[br][code]callable[/code]  回调方法
##[br][code]priority[/code]  优先级，值越小越先被调用
func add_callable(id, callable: Callable, priority: int = 10):
	# 获取这个信号的队列
	var queue : PriorityQueue
	if _signal_to_queue_map.has(id):
		queue = _signal_to_queue_map[id] as PriorityQueue
	else:
		queue = PriorityQueue.new()
		_signal_to_queue_map[id] = queue
	
	# 添加 callable 到这个信号的对列里
	if not queue.has_item(callable):
		queue.add_item(callable, priority)


##  断开连接优先级队列
##[br]
##[br][code]id[/code]  
##[br][code]callable[/code]  
func remove_callable(id, callable: Callable):
	var queue : PriorityQueue
	if _signal_to_queue_map.has(id):
		queue = _signal_to_queue_map[id] as PriorityQueue
		queue.remove_item(callable)


##  调用 [Callable]
##[br]
##[br][code]id[/code]  对这个id的 [Callable] 进行调用
##[br][code]params[/code]  参数列表
func call_callable(id, params: Array = []):
	var queue = _signal_to_queue_map.get(id) as PriorityQueue
	if queue:
		for item in queue.get_items():
			item.callv(params)

